package com.luo.d3s.light.jpa.ec.application.service.impl;

import com.luo.d3s.core.application.assmebler.PageResponseAssembler;
import com.luo.d3s.core.application.dto.MultiResponse;
import com.luo.d3s.core.application.dto.PageResponse;
import com.luo.d3s.core.application.dto.SingleResponse;
import com.luo.d3s.light.jpa.ec.application.assembler.CategoryAssembler;
import com.luo.d3s.light.jpa.ec.application.dto.query.CategoryPageQuery;
import com.luo.d3s.light.jpa.ec.application.dto.vo.CategoryTreeVo;
import com.luo.d3s.light.jpa.ec.application.dto.vo.CategoryVo;
import com.luo.d3s.light.jpa.ec.application.service.CategoryQueryService;
import com.luo.d3s.light.jpa.ec.domain.base.BizId;
import com.luo.d3s.light.jpa.ec.domain.category.Category;
import com.luo.d3s.light.jpa.ec.domain.category.CategoryRepository;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * 分类查询服务实现类
 *
 * @author luohq
 * @date 2023-01-05 11:23
 */
@Service
@CacheConfig(cacheNames = CategoryQueryService.CATEGORY_TREE_CACHE_NAME)
public class CategoryQueryServiceImpl implements CategoryQueryService {


    @Resource
    private CategoryRepository categoryRepository;

    @Override
    public SingleResponse<CategoryVo> findCategory(Long categoryId) {
        Category category = this.categoryRepository.findById(BizId.fromValue(categoryId)).orElse(null);
        //Category category = this.categoryRepository.findById_id(categoryId);
        return SingleResponse.of(CategoryAssembler.toCategoryVo(category));
    }

    @Override
    public PageResponse<CategoryVo> findCategoryPage(CategoryPageQuery categoryPageQuery) {
        PageResponse<Category> pageResp = this.categoryRepository.findPage(categoryPageQuery);
        return PageResponseAssembler.toPageResp(pageResp, CategoryAssembler::toCategoryVo);
    }

    @Cacheable(key = "#p0?:'root'")
    @Override
    public MultiResponse<CategoryTreeVo> findCategoryTree(Long categoryId) {
        //查询分类ID对应的根分类TreeDto
        List<CategoryTreeVo> rootCategoryTreeVoList = this.categoryRepository.findRootCategoryTreeVoList(categoryId);
        //递归查询子分类列表
        this.extractCategoryTree(rootCategoryTreeVoList);
        //返回递归查询结果
        return MultiResponse.of(rootCategoryTreeVoList);
    }

    private void extractCategoryTree(List<CategoryTreeVo> rootCategoryTreeVoList) {
        //若上级分类列表为空，则直接返回
        if (CollectionUtils.isEmpty(rootCategoryTreeVoList)) {
            return;
        }
        //遍历上级分类列表，依次查询其子分类李彪
        rootCategoryTreeVoList.stream()
                .forEach(curParentCategoryTreeDto -> {
                    //查询当前分类的子分类TreeDto列表
                    List<CategoryTreeVo> subCategoryTreeVoList = this.categoryRepository.findSubCategoryTreeVoList(curParentCategoryTreeDto.getId());
                    //设置当前分类的子分类TreeDto列表
                    curParentCategoryTreeDto.setSubCategories(subCategoryTreeVoList);
                    //递归设置子分类
                    extractCategoryTree(subCategoryTreeVoList);
                });
    }

}
